package com.esd.crm.controller;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.esd.crm.Constants;
import com.esd.crm.entity.Doc;
import com.esd.crm.entity.DocInformation;
import com.esd.crm.service.DocInformationService;
import com.esd.crm.service.DocService;
import com.esd.crm.util.KitService;
import com.esd.vo.ReturnResult;

@RestController
@RequestMapping("/docinformation")
public class DocInformationController {
	
	@Value(value = "${tempFilePath}")
	private String tempFilePath; // 刚上传文件的缓存目录
	@Value(value = "${fileNameSpliter}")
	private String fileNameSpliter;// 新旧文件名分隔符
	@Value(value = "${resourceFilePath}")
	private String resourceFilePath;// 文件存放路径
	
	@Autowired
	DocService docService;
	@Autowired
	DocInformationService docInformationService;

	private Logger logger = Logger.getLogger(DocInformationController.class);
	
	@RequestMapping(value="singleUpload",method=RequestMethod.GET)
	public ModelAndView uploadGet(HttpServletRequest request,RedirectAttributes redirectAttributes){
		//docId是指当前信息条的id，不是图片的id
		String docId=request.getParameter("id");
		System.out.println("value=singleUpload，get方法，请求中获取的id："+docId);
		return new ModelAndView("doc/upload","docId",docId);
	}
	
	@RequestMapping(value = "/singleUpload", method = RequestMethod.POST)
	@ResponseBody
	public void uploadPost(HttpSession session, HttpServletRequest request,
			           @RequestParam MultipartFile file) {
		
		String docId=(String)request.getParameter("docId");
		System.out.println("这条主信息的id："+docId);
		
		List<Doc> docs=docService.findOneByDocId1(docId);
		for(Doc a:docs){
			System.out.print("添加文件的信息条的信息"+a+"-");
		}
		System.out.println( );
		
		//不知道这块干啥的，感觉没用，下面9行
		if(docs.size()>1) {
			System.out.println("docs.size()==>"+docs.size());
			int m = 0;
			for (Iterator<Doc> iterator = docs.iterator(); iterator.hasNext();) {
				Doc docc =  iterator.next();
				System.out.println(m+"===这块我感觉没用，如果打印，证明有用，重新看DocInformationController（也许是预防id重复）====:"+docc.getId());
				System.out.println(m+"===这块我感觉没用，如果打印，证明有用，重新看DocInformationController====:"+docc.getDocName());
				m++;
			}
		}
		
		//创建文件存放的路径和目录，作为临时存储，然后再把临时目录里的文件存放到数据库中
		String path="_"+docId;
		//临时目录是doc/_docId/****,后面js很可能修改（photo-->doc）
		String filepath=session.getServletContext().getRealPath("doc/" + path + "/");
		System.out.println("!!!filePath:"+filepath);
		session.setAttribute("filepath", filepath);
		File f = new File(filepath);
		if (!f.isDirectory()) {
			f.mkdirs();
		}
		
		String originalFilename;
		String fileName = null;
		try {
			originalFilename = file.getOriginalFilename();
			fileName = KitService.getUUID() + fileNameSpliter + originalFilename;
			if (originalFilename != null) {
				String[] split = originalFilename.split("\\.");
				if (split != null && split.length > 0){
					file.transferTo(new File(filepath + "/"	+fileName));
				}
			}
		} catch (IllegalStateException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		
		DocInformation docInformation=new DocInformation();
		docInformation.setBusinessId(docId);
		docInformation.setOriginalFileName(file.getOriginalFilename());
		docInformation.setFileName(fileName);
		
		docInformationService.addFile(docInformation, request, session);
	}
	
	@RequestMapping(value = "/getFile", method = RequestMethod.GET)
	public ModelAndView imageGet(HttpServletRequest request, HttpSession session) {
		String docId= request.getParameter("id");
		Map<String, Object> map = new HashMap<String, Object>();
      //这个找出来的是文件的信息属性
		List<DocInformation> docss= docInformationService.getFileListByBusinessId(docId);
                  for(DocInformation aa:docss){ System.out.print(aa+",");  }
                System.out.println();
		// 如果是图片
		// =====================================
		map.put("src", docss);
		
		return new ModelAndView("doc/docshow", map);
	}
	
	
	@RequestMapping(value = "/showImage", method = RequestMethod.GET)
	public void showImage(String id, HttpServletRequest request, HttpServletResponse response, HttpSession session){
		System.out.println("我是showImage");
		DocInformation docInfor = docInformationService.selectByPrimaryKey(id);
		String name=docInfor.getFileName();
		String fileType = name.split("\\.")[name.split("\\.").length-1];
		String contentType = null;
		
		if (fileType == "png") {
			contentType = "image/png; charset=utf-8";
		}
		if (fileType == "bmp") {
			contentType = "image/bmp; charset=utf-8";
		}
		if (fileType == "gif") {
			contentType = "image/gif; charset=utf-8";
		}
		if (fileType == "jpg") {
			contentType = "image/jpeg; charset=utf-8";
		}
		if (fileType == "pdf") {
			contentType = "application/pdf; charset=utf-8";
		}
		if (fileType == "txt") {
			contentType = "text/plain; charset=utf-8";
		}
		if (fileType == "doc") {
			contentType = "application/msword; charset=utf-8";
		}
		if (fileType == "xls") {
			contentType = "application/vnd.ms-excel; charset=utf-8";
		}
		if (fileType == "ppt") {
			contentType = "application/vnd.ms-powerpoint; charset=utf-8";
		}
		
		try {
			response.setContentType(contentType);
			response.getOutputStream().write(docInfor.getFile());

			response.getOutputStream().close();
			response.flushBuffer();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	@ResponseBody
	@RequestMapping(value = "/deleteFile", method = RequestMethod.POST)
	public ReturnResult deletePhoto(HttpServletRequest request,HttpSession session) {
		String docId=request.getParameter("id");
		boolean b = docInformationService.deleteByPrimaryKey(docId);
		
		if(b) {
			return ReturnResult.success();
		}
		if(!b) {
			System.out.println("数据库图片删除失败");
		}
		return ReturnResult.fail();
	}
	
    // 根据文件id返回该文件在资源文件中的网络路径, 以供下载
	@RequestMapping(value = "/download", method = RequestMethod.POST)
	public void download_post(@RequestParam(value = "id", required = true) String id,
			HttpServletRequest request, HttpServletResponse response) {
		System.out.println("*********  下载文件   开始*********");
		logger.info("*********  下载文件   开始*********");	
	    
		List<DocInformation> docInfor = docInformationService.getFileListByBusinessId(id);
		String packName = id+"@esd.zip"; 
		String url = request.getSession().getServletContext().getRealPath(resourceFilePath);
		
//		DocInformationController docInformationController = new DocInformationController();
//		docInformationController.downZIP(docInfor,packName,url);
		System.out.println("--------------------------------");
		downZIP(docInfor,packName,url);
		System.out.println("--------------------------------");
		//TODO
		File file = new File(url+File.separator+packName);
		
		if(!file.exists() || !file.isFile()){
			System.out.println("文件不存在！");
			logger.error("文件不存在");
		}else{
			System.out.println("文件存在！");
			// 清空response
			response.reset();
			String mimeType = request.getSession().getServletContext().getMimeType(packName);
			response.setContentType(mimeType);
			response.setHeader("Content-Disposition", "attachment; filename=" + packName);
			
			BufferedInputStream bis = null;
			OutputStream os = null;
			try {
				bis = new BufferedInputStream(new FileInputStream(file));
				byte[] buf = new byte[1024];
		        os = response.getOutputStream();
		        int len = 0;
		        while ((len = bis.read(buf)) > 0){
		        	os.write(buf, 0, len);
		        }
			}catch (IOException e) {
		        logger.info("下载文件失败，请联系管理员");
		        return;
		    }finally{
		        try {
		        	bis.close();
		        	os.flush();
		        	os.close();
		        } catch (IOException e) {
		          e.printStackTrace();
		        }
		    }
		}
	}
	
	/**
	 * 生成ZIP
	 * @param docInfor 当前文件/照片的所有信息
	 * @param packName id+"@esd.zip
	 * @param url 当前文件/照片存储路径
	 */
	public  int downZIP(List<DocInformation> docInfor,String packName,String url){
		System.out.println("下载部分，生成zip包");
		System.out.println("file================"+url + Constants.SLASH + packName);
		
		if(!new File(url).exists()){
			new File(url).mkdirs();
		}
		File zipFile = new File( url + Constants.SLASH + packName );
		if(zipFile.exists()){
			zipFile.delete();
		}
		
		try {
			zipFile.createNewFile();
			
			FileOutputStream fos = new FileOutputStream(zipFile);
			ZipOutputStream zos = new ZipOutputStream(new BufferedOutputStream(fos));
			
			// writeInZIP(list, zos, Constants.WAV,url);
			writeInZIP(docInfor, zos, url);
			System.out.println("信息压入zip文件完成");
			zos.close();// 不关闭,最后一个文件写入为0kb
			fos.flush();
			fos.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return 1;
	}
	
	/**
	 * 读取数据库文件,压入zip文件中
	 * @param docInfor 当前文件/照片的所有信息
	 * @param zos ZipOutputStream，这玩应对象，貌似是zip输入流
	 * @param url 当前文件/照片存储路径
	 */
	public  void writeInZIP(List<DocInformation> docInfor,ZipOutputStream zos,String url){
		System.out.println("读取数据库文件，压入zip包中");
		
		for(Iterator<DocInformation> iterator = docInfor.iterator(); iterator.hasNext() ; ){
			
			byte[] bufs = new byte[1024*10];
			DocInformation docInformation = (DocInformation)iterator.next();
			String fileName = docInformation.getFileName();
			
			// 创建ZIP实体,并添加进压缩包,按原目录结构
			ZipEntry zipEntry = null;
			zipEntry = new ZipEntry(fileName);
			
			try {
				zos.putNextEntry(zipEntry);
				byte[] data = null;
				//这个id是上传的文件/图片的id
				System.out.println("docInformation.getId():"+docInformation.getId());
				
				docInformation = docInformationService.selectByPrimaryKey(docInformation.getId());
				data = docInformation.getFile();
				if(data != null){
					InputStream is =new ByteArrayInputStream(data);
					// 读取待压缩的文件并写进压缩包里
					BufferedInputStream bis = new BufferedInputStream(is, 1024);
					int read;
					while ((read = bis.read(bufs)) > 0) {
						zos.write(bufs, 0, read);
					}
					bis.close();
					is.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	
	
	
	
	
}
